﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;

namespace Dapper.Contrib.Tests
{
	/// <summary>
	/// This is a test case for the way my company is trying to utilize dapper. explaining further the question from http://stackoverflow.com/questions/8593871/dapper-propinfo-setter-for-inherited-entityset-from-abstract-class-reference-is
	/// ---
	/// Ideally it would be awesome if we could just build it directly off of the order object and keep it abstract. However, even if we were able to utilize the public MerchantOrder or Aution Order that would be great as well. 
	/// </summary>
	class JohnZDapperFailTest
	{
		string _ConnectionString = Dapper.Contrib.Tests.Properties.Settings.Default.Database1ConnectionString1;

		/// <summary>
		/// going by the default of Orders having an inheritance modifier of abstract we get this error - Instances of abstract classes cannot be created.
		/// change it to none and  everything works fine - this is not something we want to have to succumb to so we can ensure concrete classes
		/// NOTE - RowVersion being internal has no effect on object creation. 
		/// </summary>
		public void GetOrdersWithMiscDataFromOrdersObject()
		{
			int[] orderIds = new int[] { 1, 2, 3, 4 };
			StringBuilder sql = new StringBuilder();
			sql.Append("SELECT o.*, c.* from Orders as o ");
			sql.Append("left join Customers as c on o.CustomerID = c.CustomerID ");
			sql.Append("where o.OrderID in (" + string.Join(",", orderIds) + ") ");
			sql.Append("order by o.OrderID ");

			IEnumerable<Order> results;
			using (var connection = new SqlConnection(_ConnectionString))
			{
				try
				{
					connection.Open();
					results = connection.Query<Order, Customer, Order>(sql.ToString(),
						(o, c) => { o.Customer = c; return o; },
						splitOn: "CustomerID");
				}
				catch (Exception e)
				{					
					throw e;
				}
			}

			if (results == null || results.Count() == 0)
			{
				throw new Exception("no results found! This is no good!");
			}
		}

		/// <summary>
		/// if RowVersion in Orders is set to be internal it will throw an error inside of "GetSettableProps" for "Object reference not set to an instance of an object."
		/// Change RowVersion to Public to get it to behave differently - and Shipments will crash for the same reason
		/// This function will not work at all because it cannot initialize the misc objects it is not fetching data for. 
		/// </summary>
		public void GetOrdersWithMiscDataFromMerchantOrderObject()
		{
			int[] orderIds = new int[]{1,2,3,4};
			StringBuilder sql = new StringBuilder();
			sql.Append("SELECT o.*, c.* from Orders as o ");
			sql.Append("left join Customers as c on o.CustomerID = c.CustomerID ");
			sql.Append("where o.OrderID in (" + string.Join(",", orderIds) + ") ");
			sql.Append("order by o.OrderID ");

			IEnumerable<MerchantOrder> results;
			using (var connection = new SqlConnection(_ConnectionString))
			{
				try
				{
					connection.Open();
					results = connection.Query<MerchantOrder, Customer, MerchantOrder>(sql.ToString(),
						(o, c) => { o.Customer = c; return o; },
						splitOn: "CustomerID");
				}
				catch (Exception e)
				{					
					throw e;
				}
			}

			if (results == null || results.Count() == 0)
			{
				throw new Exception("no results found! This is no good!");
			}
		}
	}
}
